package com.southminority.ethnic.controller.admin.news;

import com.southminority.ethnic.common.result.PageResult;
import com.southminority.ethnic.common.result.R;
import com.southminority.ethnic.controller.alioss.vo.OssFileReqVo;
import com.southminority.ethnic.pojo.News;
import com.southminority.ethnic.service.alioss.OssService;
import com.southminority.ethnic.service.news.NewsService;
import com.southminority.ethnic.controller.news.vo.NewsVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.parameters.RequestBody;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 新闻管理后台控制器
 * 
 * @author SouthMinority
 */
@Slf4j
@Tag(name = "11 - 新闻资讯管理API", description = "【后台】新闻、公告、研究进展等模块的增删改查接口")
@RestController
@RequestMapping("/admin/news")
@CrossOrigin
public class NewsAdminController {

    private final NewsService newsService;
    private final OssService ossService;

    public NewsAdminController(NewsService newsService, OssService ossService) {
        this.newsService = newsService;
        this.ossService = ossService;
    }

    @GetMapping("/page")
    @Operation(summary = "分页和条件查询新闻", description = "后台管理使用的新闻列表接口，支持多种条件筛选和分页。")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "查询成功"),
            @ApiResponse(responseCode = "500", description = "查询失败")
    })
    public R<PageResult<NewsVO>> getNewsPage(
            @Parameter(description = "当前页码", example = "1") @RequestParam(defaultValue = "1") Integer page,
            @Parameter(description = "每页显示数量", example = "10") @RequestParam(defaultValue = "10") Integer size,
            @Parameter(description = "搜索关键词（标题）", example = "研讨会") @RequestParam(required = false) String keyword,
            @Parameter(description = "分类", example = "学术会议") @RequestParam(required = false) String category,
            @Parameter(description = "新闻类型", example = "news", schema = @Schema(allowableValues = {"news", "progress", "announcement"})) @RequestParam(required = false) String newsType,
            @Parameter(description = "状态", example = "1", schema = @Schema(description = "1-已发布, 0-草稿", type = "integer", allowableValues = {"1", "0"})) @RequestParam(required = false) Integer status,
            @Parameter(description = "是否置顶", example = "1", schema = @Schema(description = "1-是(轮播图), 0-否", type = "integer", allowableValues = {"1", "0"})) @RequestParam(required = false) Integer isTop) {
        try {
            PageResult<NewsVO> pageResult = newsService.getNewsPageForAdmin(page, size, keyword, category, newsType, status, isTop);
            return R.ok(pageResult);
        } catch (Exception e) {
            log.error("分页查询新闻失败", e);
            return R.fail("查询失败: " + e.getMessage());
        }
    }

    @GetMapping("/detail/{id}")
    @Operation(summary = "获取单篇新闻的详细信息（用于编辑）", description = "根据新闻ID查询，返回其完整信息，包括草稿和已删除状态的内容。")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "获取成功"),
            @ApiResponse(responseCode = "404", description = "新闻不存在"),
            @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public R<NewsVO> getNewsDetail(@Parameter(description = "新闻的唯一ID", example = "1", required = true) @PathVariable Long id) {
        try {
            NewsVO newsVO = newsService.getNewsDetailForAdmin(id);
            return R.ok(newsVO);
        } catch (Exception e) {
            log.error("获取新闻详情失败", e);
            return R.fail("获取失败: " + e.getMessage());
        }
    }

    @PostMapping("/create")
    @Operation(summary = "创建新闻", description = "创建新的新闻条目。")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "创建成功"),
            @ApiResponse(responseCode = "400", description = "请求参数错误"),
            @ApiResponse(responseCode = "500", description = "创建失败")
    })
    public R<NewsVO> createNews(
            @Parameter(description = "新闻创建数据", required = true)
            @RequestBody @Valid News news
    ) {
        try {
            NewsVO result = newsService.createNews(news);
            return R.ok(result);
        } catch (Exception e) {
            return R.fail("新闻创建失败: " + e.getMessage());
        }
    }

    @PutMapping("/update/{id}")
    @Operation(summary = "根据ID更新新闻信息", description = "提供新闻的ID和更新后的信息，对现有记录进行修改。")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "更新成功，返回更新后的新闻信息"),
            @ApiResponse(responseCode = "400", description = "请求参数错误"),
            @ApiResponse(responseCode = "404", description = "新闻不存在"),
            @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public R<NewsVO> updateNews(
            @Parameter(description = "要更新的新闻ID", example = "1", required = true) @PathVariable Long id,
            @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "包含更新字段的新闻JSON对象", required = true,
                    content = @Content(schema = @Schema(implementation = News.class)))
            @org.springframework.web.bind.annotation.RequestBody News news) {
        try {
            log.info("管理员更新新闻: ID={}, 标题={}", id, news.getTitle());
            NewsVO newsVO = newsService.updateNews(id, news);
            return R.ok(newsVO);
        } catch (Exception e) {
            log.error("更新新闻失败", e);
            return R.fail("更新失败: " + e.getMessage());
        }
    }

    @DeleteMapping("/delete/{id}")
    @Operation(summary = "根据ID逻辑删除新闻", description = "将指定ID的新闻状态设置为-1（已删除），并非物理删除。")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "删除成功"),
            @ApiResponse(responseCode = "404", description = "新闻不存在"),
            @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public R<Boolean> deleteNews(@Parameter(description = "要删除的新闻ID", example = "1", required = true) @PathVariable Long id) {
        try {
            log.info("管理员删除新闻: ID={}", id);
            boolean result = newsService.deleteNews(id);
            return R.ok(result);
        } catch (Exception e) {
            log.error("删除新闻失败", e);
            return R.fail("删除失败: " + e.getMessage());
        }
    }

    @DeleteMapping("/batch-delete")
    @Operation(summary = "批量逻辑删除新闻", description = "传入一个ID列表，批量将对应的新闻状态设置为-1。")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "批量删除成功"),
            @ApiResponse(responseCode = "400", description = "ID列表为空"),
            @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public R<Boolean> batchDeleteNews(@RequestBody(description = "包含多个新闻ID的数组", required = true,
            content = @Content(schema = @Schema(type = "array", implementation = Long.class))) List<Long> ids) {
        try {
            log.info("管理员批量删除新闻: IDs={}", ids);
            boolean result = newsService.batchDeleteNews(ids);
            return R.ok(result);
        } catch (Exception e) {
            log.error("批量删除新闻失败", e);
            return R.fail("批量删除失败: " + e.getMessage());
        }
    }

    @PutMapping("/status/{id}")
    @Operation(summary = "更新新闻状态", description = "更新单篇新闻的状态，如发布（1）和草稿（0）。")
    @Parameters({
            @Parameter(name = "id", description = "新闻ID", example = "1", required = true),
            @Parameter(name = "status", description = "新的状态值", example = "0", required = true,
                    schema = @Schema(description = "1-已发布, 0-草稿", type = "integer", allowableValues = {"1", "0"}))
    })
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "状态更新成功"),
            @ApiResponse(responseCode = "400", description = "参数错误"),
            @ApiResponse(responseCode = "404", description = "新闻不存在"),
            @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public R<Boolean> updateNewsStatus(
            @PathVariable Long id,
            @RequestParam Integer status) {
        try {
            log.info("管理员更新新闻状态: ID={}, Status={}", id, status);
            boolean result = newsService.updateNewsStatus(id, status);
            return R.ok(result);
        } catch (Exception e) {
            log.error("更新新闻状态失败", e);
            return R.fail("更新状态失败: " + e.getMessage());
        }
    }

    @PutMapping("/top/{id}")
    @Operation(summary = "设置新闻置顶状态", description = "设置或取消单篇新闻的置顶状态。")
    @Parameters({
            @Parameter(name = "id", description = "新闻ID", example = "1", required = true),
            @Parameter(name = "isTop", description = "是否置顶", example = "1", required = true,
                    schema = @Schema(description = "1-是, 0-否", type = "integer", allowableValues = {"1", "0"}))
    })
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "设置成功"),
            @ApiResponse(responseCode = "400", description = "参数错误"),
            @ApiResponse(responseCode = "404", description = "新闻不存在"),
            @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public R<Boolean> setNewsTop(
            @PathVariable Long id,
            @RequestParam Integer isTop) {
        try {
            log.info("管理员设置新闻置顶: ID={}, IsTop={}", id, isTop);
            boolean result = newsService.setNewsTopStatus(id, isTop);
            return R.ok(result);
        } catch (Exception e) {
            log.error("设置新闻置顶失败", e);
            return R.fail("设置失败: " + e.getMessage());
        }
    }

    @PostMapping(value = "/upload-cover", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    @Operation(summary = "上传新闻封面图片", description = "上传图片文件到OSS，并返回可访问的URL。")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "上传成功，返回图片URL"),
            @ApiResponse(responseCode = "500", description = "上传失败")
    })
    public R<String> uploadCoverImage(@Parameter(description = "包含文件和分类信息的表单") @Valid @ModelAttribute OssFileReqVo ossFileReqVo) {
        try {
            // 默认设置新闻图片分类
            if (ossFileReqVo.getClassName() == null || ossFileReqVo.getClassName().isEmpty()) {
                ossFileReqVo.setClassName("news");
            }
            
            log.info("管理员上传新闻封面图片: 分类={}", ossFileReqVo.getClassName());
            String imageUrl = ossService.upload(ossFileReqVo.getFile(), ossFileReqVo.getClassName());
            return R.ok(imageUrl);
        } catch (Exception e) {
            log.error("上传新闻封面图片失败", e);
            return R.fail("上传失败: " + e.getMessage());
        }
    }

    @GetMapping("/test")
    @Operation(summary = "测试接口连通性", description = "一个简单的GET请求，用于检查服务是否正常运行。")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "服务正常")
    })
    public R<String> test() {
        return R.ok("新闻管理后台服务正常");
    }
} 
